Passed
Push — 16.1 ( 3ae7fc...22ba35 )
by Ralf
12:47
created

window.egw_LAB.wait   F

Complexity

Conditions 25
Paths > 20000

Size

Total Lines 208

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 25
c 1
b 0
f 0
nc 622082
nop 0
dl 0
loc 208
rs 2

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

Complexity

Complex classes like window.egw_LAB.wait often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
/**
2
 * EGroupware clientside API object
3
 *
4
 * @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
5
 * @package etemplate
6
 * @subpackage api
7
 * @link http://www.egroupware.org
8
 * @author Andreas Stöckel (as AT stylite.de)
9
 * @author Ralf Becker <[email protected]>
10
 * @version $Id$
11
 */
12
13
/*egw:uses
14
	egw_core;
15
	egw_debug;
16
	egw_preferences;
17
	egw_lang;
18
	egw_links;
19
	egw_open;
20
	egw_user;
21
	egw_config;
22
	egw_images;
23
	egw_jsonq;
24
	egw_files;
25
	egw_json;
26
	egw_store;
27
	egw_tooltip;
28
	egw_css;
29
	egw_calendar;
30
	egw_ready;
31
	egw_data;
32
	egw_tail;
33
	egw_inheritance;
34
	egw_message;
35
	egw_notification;
36
	app_base;
37
*/
38
39
(function()
40
{
41
	"use strict";
42
43
	var debug = false;
44
	var egw_script = document.getElementById('egw_script_id');
45
	var start_time = (new Date).getTime();
46
	if(typeof console != "undefined" && console.time) console.time("egw");
47
48
	// set opener as early as possible for framework popups (not real popups)
49
	if (!window.opener && window.parent !== window)
50
	{
51
		try {
52
			if (window.parent.framework && typeof window.parent.framework.popup_idx == 'function' &&
53
				window.parent.framework.popup_idx.call(window.parent.framework, window) !== undefined)
54
			{
55
				window.opener = window.parent;
56
			}
57
		}
58
		catch(e) {
59
			// ignore SecurityError exception if opener is different security context / cross-origin
60
		}
61
	}
62
	// Flag for if this is opened in a popup
63
	var popup = (window.opener != null);
64
65
	window.egw_webserverUrl = egw_script.getAttribute('data-url');
66
	window.egw_appName = egw_script.getAttribute('data-app');
67
68
	// check if egw object was injected by window open
69
	if (typeof window.egw == 'undefined')
70
	{
71
		try {
72
			// try finding it in top or opener's top
73
			if (window.opener && typeof window.opener.top.egw != 'undefined')
74
			{
75
				window.egw = window.opener.top.egw;
76
				if (typeof window.opener.top.framework != 'undefined') window.framework = window.opener.top.framework;
77
				popup = true;
78
				if (debug) console.log('found egw object in opener');
0 ignored issues
show
Debugging Code introduced by
console.log looks like debug code. Are you sure you do not want to remove it?
Loading history...
79
			}
80
		}
81
		catch(e) {
82
			// ignore SecurityError exception if opener is different security context / cross-origin
83
		}
84
		try {
85
			// try finding it in top
86
			if (typeof window.egw == 'undefined' && window.top && typeof window.top.egw != 'undefined')
87
			{
88
				window.egw = window.top.egw;
89
				if (typeof window.top.framework != 'undefined') window.framework = window.top.framework;
90
				if (debug) console.log('found egw object in top');
91
			}
92
		}
93
		catch(e) {
94
			// ignore SecurityError exception if top is different security context / cross-origin
95
		}
96
		if (typeof window.egw == 'undefined')
97
		{
98
			window.egw = {
99
				prefsOnly: true,
100
				webserverUrl: egw_webserverUrl
101
			};
102
			if (debug) console.log('creating new egw object');
103
		}
104
	}
105
	else if (debug) console.log('found injected egw object');
106
107
	// check for a framework object
108
	if (typeof window.framework == 'undefined')
109
	{
110
		try {
111
			// try finding it in top or opener's top
112
			if (window.opener && typeof window.opener.top.framework != 'undefined')
113
			{
114
				window.framework = window.opener.top.framework;
115
				if (debug) console.log('found framework object in opener top');
116
			}
117
		}
118
		catch(e) {
119
			// ignore SecurityError exception if opener is different security context / cross-origin
120
		}
121
		try {
122
			if (typeof window.framework == 'undefined' && window.top && typeof window.top.framework != 'undefined')
123
			{
124
				window.framework = window.top.framework;
125
				if (debug) console.log('found framework object in top');
126
			}
127
		}
128
		catch(e) {
129
			// ignore SecurityError exception if top is different security context / cross-origin
130
		}
131
		// if framework not found, but requested to check for it, redirect to cd=yes to create it
132
		if (typeof window.framework == 'undefined' && egw_script.getAttribute('data-check-framework') &&
133
			!window.location.search.match(/[&?]cd=/))
134
		{
135
			window.location.search += window.location.search ? "&cd=yes" : "?cd=yes";
136
		}
137
	}
138
	try {
139
		if (typeof egw == 'function') egw(window).message;
140
	}
141
	catch (e) {
142
		console.log('Security exception accessing window specific egw object --> creating new one', e);
143
		window.egw = {
144
			prefsOnly: true,
145
			webserverUrl: egw_webserverUrl
146
		};
147
	}
148
149
	// focus window / call window.focus(), if data-window-focus is specified
150
	var window_focus = egw_script.getAttribute('data-window-focus');
151
	if (window_focus && JSON.parse(window_focus))
152
	{
153
		window.focus();
154
	}
155
156
	window.egw_LAB = $LAB.setOptions({AlwaysPreserveOrder:true,BasePath:window.egw_webserverUrl+'/'});
157
	var include = JSON.parse(egw_script.getAttribute('data-include'));
158
	window.egw_LAB.script(include).wait(function()
159
	{
160
		// We need to override the globalEval to mitigate potential execution of
161
		// script tag. This issue is relevant to jQuery 1.12.4, we need to check
162
		// if we still need this after upgrading jQuery.
163
		jQuery.extend({
164
			globalEval:function(data){}
165
		});
166
167
		// call egw.link_handler, if attr specified
168
		var egw_redirect = egw_script.getAttribute('data-egw-redirect');
169
		if (egw_redirect)
170
		{
171
			// set sidebox for tabed templates, we need to set it now, as framework will not resent it!
172
			var sidebox = egw_script.getAttribute('data-setSidebox');
173
			if (window.framework && sidebox)
174
			{
175
				window.framework.setSidebox.apply(window.framework, JSON.parse(sidebox));
176
			}
177
			egw_redirect = JSON.parse(egw_redirect);
178
			egw.link_handler.apply(egw, egw_redirect);
179
			return;	// do NOT execute any further code, as IE(11) will give errors because framework already redirects
180
		}
181
182
		// call egw_refresh on opener, if attr specified
183
		var refresh_opener = egw_script.getAttribute('data-refresh-opener');
184
		if (refresh_opener && window.opener)
185
		{
186
			refresh_opener = JSON.parse(refresh_opener) || {};
187
			window.opener.egw(window.opener).refresh.apply(egw(window.opener), refresh_opener);
188
		}
189
190
		// close window / call window.close(), if data-window-close is specified
191
		var window_close = egw_script.getAttribute('data-window-close');
192
		if (window_close)
193
		{
194
			if (typeof window_close == 'string' && window_close !== '1')
195
			{
196
				alert(window_close);
197
			}
198
			// If there's a message & opener, set it
199
			if(window.opener && egw_script.getAttribute('data-message'))
200
			{
201
				egw(window.opener).message(JSON.parse(egw_script.getAttribute('data-message')));
202
			}
203
			egw(window).close();
204
		}
205
206
		// call egw.open_link, if popup attr specified
207
		var egw_popup = egw_script.getAttribute('data-popup');
208
		if (egw_popup)
209
		{
210
			egw_popup = JSON.parse(egw_popup) || [];
211
			egw.open_link.apply(egw, egw_popup);
212
		}
213
214
		if(typeof console != "undefined" && console.timeEnd) console.timeEnd("egw");
215
		var end_time = (new Date).getTime();
216
		var gen_time_div = jQuery('#divGenTime_'+window.egw_appName);
217
		if (!gen_time_div.length) gen_time_div = jQuery('.pageGenTime');
218
		var gen_time_async = jQuery('.asyncIncludeTime').length > 0 ? jQuery('.asyncIncludeTime'):
219
				gen_time_div.append('<span class="asyncIncludeTime"></span>').find('.asyncIncludeTime');
220
		gen_time_async.text(egw.lang('async includes took %1s', (end_time-start_time)/1000));
221
222
		// Make sure opener knows when we close - start a heartbeat
223
		if((popup || window.opener) && window.name != '')
224
		{
225
			// Timeout is 5 seconds, but it iks only applied(egw_utils) when something asks for the window list
226
			window.setInterval(function() {
227
				egw().storeWindow(this.egw_appName, this);
228
			}, 2000);
229
		}
230
231
		// instanciate app object
232
		var appname = window.egw_appName;
233
		if (app && typeof app[appname] != 'object' && typeof app.classes[appname] == 'function')
234
		{
235
			app[appname] = new app.classes[appname]();
236
		}
237
238
		// set sidebox for tabed templates
239
		var sidebox = egw_script.getAttribute('data-setSidebox') || jQuery('#late-sidebox').attr('data-setSidebox');
240
		if (window.framework && sidebox && sidebox !== 'null')
241
		{
242
			window.framework.setSidebox.apply(window.framework, JSON.parse(sidebox));
243
		}
244
245
		var resize_attempt = 0;
246
		var resize_popup = function()
247
		{
248
			var $main_div = jQuery('#popupMainDiv');
249
			var $et2 = jQuery('.et2_container');
250
			var w = {
251
				width: egw_getWindowInnerWidth(),
252
				height: egw_getWindowInnerHeight()
253
			};
254
			// Use et2_container for width since #popupMainDiv is full width, but we still need
255
			// to take padding/margin into account
256
			var delta_width = w.width - ($et2.outerWidth(true) + ($main_div.outerWidth(true) - $main_div.width()));
257
			var delta_height = w.height - ($et2.outerHeight(true) + ($main_div.outerHeight(true) - $main_div.height()));
258
259
			// Don't let the window gets horizental scrollbar
260
			var scrollWidth = document.body.scrollWidth - document.body.clientWidth;
261
			if (scrollWidth > 0 && scrollWidth + egw_getWindowOuterWidth() < screen.availWidth) delta_width = -scrollWidth;
262
263
			if (delta_height && egw_getWindowOuterHeight() >= egw.availHeight())
264
			{
265
				delta_height = 0;
266
			}
267
			if((delta_width != 0 || delta_height != 0) &&
268
				(delta_width >2 || delta_height >2 || delta_width<-2 || delta_height < -2))
269
			{
270
271
				if (window.framework && typeof window.framework.resize_popup != 'undefined')
272
				{
273
					window.framework.resize_popup($et2.outerWidth(true), $et2.outerHeight(true), window);
274
				}
275
				else
276
				{
277
					window.resizeTo(egw_getWindowOuterWidth() - delta_width+8, egw_getWindowOuterHeight() - delta_height);
278
				}
279
			}
280
			// trigger a 2. resize, as one is not enough, if window is zoomed
281
			if (delta_width && ++resize_attempt < 2)
282
			{
283
				window.setTimeout(resize_popup, 50);
284
			}
285
			else
286
			{
287
				resize_attempt = 0;
288
			}
289
		};
290
291
		// rest needs DOM to be ready
292
		jQuery(function() {
293
			// load etemplate2 template(s)
294
			jQuery('form.et2_container[data-etemplate]').each(function(index, node){
295
				var data = JSON.parse(node.getAttribute('data-etemplate')) || {};
296
				var currentapp = data.data.currentapp || window.egw_appName;
297
				if(popup || window.opener && !egwIsMobile())
298
				{
299
					// Resize popup when et2 load is done
300
					jQuery(node).on('load', function() {
301
						window.setTimeout(resize_popup, 50);
302
					});
303
				}
304
				var et2 = new etemplate2(node, "EGroupware\\Api\\Etemplate::ajax_process_content");
305
				et2.load(data.name,data.url,data.data);
306
				if (typeof data.response != 'undefined')
307
				{
308
					var json_request = egw(window).json();
309
					json_request.handleResponse({response: data.response});
310
				}
311
			});
312
313
			// set app-header
314
			if (window.framework && egw_script.getAttribute('data-app-header'))
315
			{
316
				egw(window).app_header(egw_script.getAttribute('data-app-header'), appname);
317
			}
318
			// display a message
319
			if (egw_script.getAttribute('data-message'))
320
			{
321
				var params = JSON.parse(egw_script.getAttribute('data-message')) || [''];
322
				egw(window).message.apply(egw(window), params);
323
			}
324
			// hide location bar for mobile browsers
325
			if (egw_script.getAttribute('data-mobile'))
326
			{
327
				window.scrollTo(0, 1);
328
			}
329
			try {
330
				// Open tutorial popup with an introduction video about egroupware
331
				if (window.framework === window.top.framework && typeof et2_dialog != 'undefined' &&
332
					!egw.preference('egw_tutorial_noautoload', 'common') &&
333
					!parseInt(document.getElementById('egw_script_id').getAttribute('data-framework-reload')) &&
334
					(!egw.config('egw_tutorial_disable', 'phpgwapi') || egw.config('egw_tutorial_disable', 'phpgwapi') == 'sidebox'))
335
				{
336
					// we need to wait until common translations are loaded
337
					egw.langRequireApp(window, 'common', function()
338
					{
339
						var buttons = [
340
							{text:egw.lang("Show now"), id:"show", image: "check", default:"true"},
341
							{text:egw.lang("Show next login"), id:"later", image: "right"},
342
							{text:egw.lang("No thanks"), id:"never", image: "cancel"}
343
						];
344
						et2_dialog.show_dialog(function (_button_id)
345
						{
346
							if (_button_id == "show" )
347
							{
348
								egw.open_link(egw.link('/index.php', 'menuaction=api.EGroupware\\Api\\Framework\\Tutorial.popup&tuid=introduction-'+egw.preference('lang')+'-0-a'),'_blank','960x580');
349
							}
350
							if(_button_id != "later")
351
							{
352
								egw.set_preference('common', 'egw_tutorial_noautoload',true);
353
							}
354
						},
355
						egw.lang('We would like to introduce you to EGroupware by showing a short introduction video.'),
356
						egw.lang('Introduction'),
357
						{}, buttons, et2_dialog.QUESTION_MESSAGE, undefined, egw(window));
358
					}, this);
359
				}
360
			}
361
			catch(e) {
362
				// ignore SecurityError exception if top is different security context / cross-origin
363
			}
364
		});
365
	});
366
367
	/**
368
	 *
369
	 */
370
	window.callManual = function()
371
	{
372
		if (window.framework)
373
		{
374
			window.framework.callManual.call(window.framework, window.location.href);
375
		}
376
	};
377
})();
378
379
/**
380
 * Call a function specified by it's name (possibly dot separated, eg. "app.myapp.myfunc")
381
 *
382
 * @param {string} _func dot-separated function name
383
 * variable number of arguments
384
 * @returns {Boolean}
385
 */
386
function et2_call(_func)
387
{
388
	var args = [].slice.call(arguments);	// convert arguments to array
389
	var func = args.shift();
390
	var parent = window;
391
392
	if (typeof _func == 'string')
393
	{
394
		var parts = _func.split('.');
395
		func = parts.pop();
396
		for(var i=0; i < parts.length; ++i)
397
		{
398
			if (typeof parent[parts[i]] != 'undefined')
399
			{
400
				parent = parent[parts[i]];
401
			}
402
			// check if we need a not yet instanciated app.js object --> instanciate it now
403
			else if (i == 1 && parts[0] == 'app' && typeof app.classes[parts[1]] == 'function')
404
			{
405
				parent = parent[parts[1]] = new app.classes[parts[1]]();
406
			}
407
		}
408
		if (typeof parent[func] == 'function')
409
		{
410
			func = parent[func];
411
		}
412
	}
413
	if (typeof func != 'function')
414
	{
415
		throw _func+" is not a function!";
416
	}
417
	return func.apply(parent, args);
418
}
419